package com.duojuhe.coremodule.system.service.impl;

import com.duojuhe.cache.SystemDictCache;
import com.duojuhe.cache.SystemSafeRefererCache;
import com.duojuhe.common.bean.UserTokenInfoVo;
import com.duojuhe.common.enums.SystemEnum;
import com.duojuhe.common.exception.base.DuoJuHeException;
import com.duojuhe.common.result.ErrorCodes;
import com.duojuhe.common.result.PageResult;
import com.duojuhe.common.result.ServiceResult;
import com.duojuhe.common.utils.encryption.md5.MD5Util;
import com.duojuhe.common.utils.page.PageHelperUtil;
import com.duojuhe.common.utils.thread.ThreadUtils;
import com.duojuhe.coremodule.BaseService;
import com.duojuhe.coremodule.system.entity.SystemDict;
import com.duojuhe.coremodule.system.entity.SystemSafeReferer;
import com.duojuhe.coremodule.system.mapper.SystemSafeRefererMapper;
import com.duojuhe.coremodule.system.pojo.dto.referer.*;
import com.duojuhe.coremodule.system.service.SystemSafeRefererService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class SystemSafeRefererServiceImpl extends BaseService implements SystemSafeRefererService {
    @Resource
    private SystemDictCache systemDictCache;
    @Resource
    private SystemSafeRefererCache systemSafeRefererCache;
    @Resource
    private SystemSafeRefererMapper systemSafeRefererMapper;

    /**
     * 项目启动时，初始系统安全白名单到缓存
     */
    @PostConstruct
    public void initSystemDictToCache() {
        log.info("=====初始系统安全白名单到缓存中开始=====");
        loadingSystemSafeRefererCache();
        log.info("=====初始系统安全白名单到缓存中结束=====");
    }

    /**
     * 【分页查询】分页查询系统安全白名单list
     * @param req
     * @return
     */
    @Override
    public ServiceResult<PageResult<List<QuerySystemSafeRefererPageRes>>> querySystemSafeRefererPageResList(QuerySystemSafeRefererPageReq req) {
        PageHelperUtil.orderByAndStartPage(req, "createTime desc,allowReferer desc, id desc");
        List<QuerySystemSafeRefererPageRes> list = systemSafeRefererMapper.querySystemSafeRefererPageResList(req);
        for (QuerySystemSafeRefererPageRes res:list){
            SystemDict dictBuiltIn = systemDictCache.getSystemDictByDictCode(res.getBuiltIn());
            res.setBuiltInName(dictBuiltIn.getDictName());
            res.setBuiltInColor(dictBuiltIn.getDictColor());
        }
        return PageHelperUtil.returnServiceResult(req,list);
    }

    /**
     * 【新增】修改系统安全白名单
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult saveSystemSafeReferer(SaveSystemSafeRefererReq req) {
        //检查安全名单是否存在
        checkSystemSafeRefererExist(req.getAllowReferer());
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前时间
        Date nowDate = new Date();
        //安全ID
        String id = MD5Util.getMD532(req.getAllowReferer());
        //构建安全对象
        SystemSafeReferer systemSafeReferer = new SystemSafeReferer();
        systemSafeReferer.setId(id);
        systemSafeReferer.setAllowReferer(req.getAllowReferer());
        systemSafeReferer.setCreateTime(nowDate);
        systemSafeReferer.setUpdateTime(nowDate);
        systemSafeReferer.setCreateUserId(userTokenInfoVo.getUserId());
        systemSafeReferer.setUpdateUserId(userTokenInfoVo.getUserId());
        systemSafeReferer.setCreateDeptId(userTokenInfoVo.getCreateDeptId());
        systemSafeReferer.setTenantId(userTokenInfoVo.getTenantId());
        systemSafeReferer.setBuiltIn(SystemEnum.YES_NO.NO.getKey());
        int row = systemSafeRefererMapper.insertSelective(systemSafeReferer);
        if (row>0){
            systemSafeRefererCache.putSystemSafeRefererCache(systemSafeReferer);
        }
        return ServiceResult.ok(systemSafeReferer);
    }

    /**
     * 【修改】修改系统安全白名单
     * @param req
     * @return
     */
    @Override
    public ServiceResult updateSystemSafeReferer(UpdateSystemSafeRefererReq req) {
        //安全白名单ID
        String id = req.getId();
        //查询数据库检查
        SystemSafeReferer safeReferer = systemSafeRefererMapper.selectByPrimaryKey(id);
        if (safeReferer == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        if (SystemEnum.YES_NO.YES.getKey().equals(safeReferer.getBuiltIn())) {
            return ServiceResult.fail(ErrorCodes.SYSTEM_SAFE_REFERER_BUILT_IN_NOT_UPDATE);
        }
        //系统安全名单
        String allowReferer = req.getAllowReferer();
        //如果不是和当前编码一致则判断是否存在
        if (!safeReferer.getAllowReferer().equals(allowReferer)){
            //检查安全名单是否存在
            checkSystemSafeRefererExist(allowReferer);
        }
        //当前登录用户
        UserTokenInfoVo userTokenInfoVo = getCurrentLoginUserInfoDTO();
        //当前时间
        Date nowDate = new Date();
        //构建安全对象
        SystemSafeReferer systemSafeReferer = new SystemSafeReferer();
        systemSafeReferer.setId(id);
        systemSafeReferer.setAllowReferer(req.getAllowReferer());
        systemSafeReferer.setUpdateTime(nowDate);
        systemSafeReferer.setUpdateUserId(userTokenInfoVo.getUserId());
        int row = systemSafeRefererMapper.updateByPrimaryKeySelective(systemSafeReferer);
        if (row>0){
            systemSafeRefererCache.putSystemSafeRefererCache(systemSafeReferer);
        }
        return ServiceResult.ok(systemSafeReferer);
    }


    /**
     * 删除系统安全白名单
     * @param req
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceResult deleteSystemSafeRefererById(SystemSafeRefererIdReq req) {
        //安全白名单ID
        String id = req.getId();
        //查询数据库检查
        SystemSafeReferer safeReferer = systemSafeRefererMapper.selectByPrimaryKey(id);
        if (safeReferer == null) {
            return ServiceResult.fail(ErrorCodes.PARAM_ERROR);
        }
        if (SystemEnum.YES_NO.YES.getKey().equals(safeReferer.getBuiltIn())) {
            return ServiceResult.fail(ErrorCodes.SYSTEM_SAFE_REFERER_BUILT_IN_NOT_DELETE);
        }
        //删除数据库
        int row = systemSafeRefererMapper.deleteByPrimaryKey(id);
        if (row>0){
            //删除缓存
            systemSafeRefererCache.deleteSystemSafeRefererById(id);
        }
        return ServiceResult.ok(id);
    }

    /**
     * 加载系统安全白名单缓存数据
     */
    @Override
    public void loadingSystemSafeRefererCache() {
        //先清除
        systemSafeRefererCache.clearSystemSafeRefererCache();
        //在插入
        systemSafeRefererCache.putSystemSafeRefererCache(systemSafeRefererMapper.selectAll());
    }

    /**
     * 清空系统安全白名单缓存数据
     */
    @Override
    public void clearSystemSafeRefererCache() {
        systemSafeRefererCache.clearSystemSafeRefererCache();
    }

    /**
     * 重置系统安全白名单缓存数据
     */
    @Override
    public ServiceResult resetSystemSafeRefererCache() {
        ThreadUtils.execute(() -> {
            try {
                //先清空之前的
                clearSystemSafeRefererCache();
                //加载新的
                loadingSystemSafeRefererCache();
            } catch (Exception e) {
                log.error("重置系统安全白名单缓存出现异常", e);
            }
        });
        return ServiceResult.ok(ErrorCodes.SUCCESS);
    }

    /**
     * 【私有方法，辅助其他接口方法使用】 检查白名单是否配置过了
     */
    private void checkSystemSafeRefererExist(String allowReferer) {
        if (StringUtils.isBlank(allowReferer)){
            throw new DuoJuHeException(ErrorCodes.SYSTEM_SAFE_REFERER_EXIST);
        }
        Example example = new Example(SystemSafeReferer.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("allowReferer", allowReferer);
        if(systemSafeRefererMapper.selectByExample(example).size()>0){
            throw new DuoJuHeException(ErrorCodes.SYSTEM_SAFE_REFERER_EXIST);
        }
    }
}
